package metrics

import (
	"gitee.com/captials-team/ubdframe/src/domain/configstc"
	v1log "gitee.com/captials-team/ubdframe/src/pkg/logs"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/push"
)

type PrometheusPushIndicator struct {
	l      v1log.ILog
	ch     chan IndicData
	pusher *push.Pusher

	conf configstc.MonitorReportConfig
}

// NewPrometheusPushIndicator 指标上报器-prometheus
func NewPrometheusPushIndicator(conf configstc.MonitorReportConfig, l v1log.ILog) *PrometheusPushIndicator {
	st := &PrometheusPushIndicator{
		l:      l,
		ch:     make(chan IndicData, 64),
		pusher: push.New(conf.Host, conf.Name),
		conf:   conf,
	}
	go st.bgReport()
	return st
}

func (ind *PrometheusPushIndicator) bgReport() {
	m := map[string]*prometheus.GaugeVec{}
	p := ind.pusher

	for {
		select {
		case data := <-ind.ch:
			ind.l.Info("[Indicator]%s: %f %s", data.Name, data.Value, data.Unit)
			var gauge *prometheus.GaugeVec
			var exist bool

			metricName := ind.conf.Namespace + "." + data.Name
			if gauge, exist = m[metricName]; !exist {
				var labels []string
				for k, _ := range data.EntireLabels() {
					labels = append(labels, k)
				}
				m[metricName] = prometheus.NewGaugeVec(prometheus.GaugeOpts{
					Namespace: ind.conf.Namespace,
					Name:      data.Name,
					Help:      "prometheus by push gateway",
				}, labels)
				gauge = m[metricName]

				p.Collector(gauge)
			}
			gauge.With(data.EntireLabels()).Set(data.Value)
			err := p.Push()
			if err != nil {
				ind.l.Error("Could not push completion time to Pushgateway: %s", err)
			}

		}
	}
}

// Report 上报数据
func (ind *PrometheusPushIndicator) Report(data IndicData) {
	ind.ch <- data
}
